package net.loststone

class EconInfoController {

    def authenticationService

    static allowedMethods = [list: "GET", create: "GET", update: "POST", save: "POST"]

    def onlyLoggedInUsers = {
        if (!authenticationService.isLoggedIn(request)) {
            //Redirect or return Forbidden
            redirect(controller:"sauron", action: "index", params: params)

            //response.sendError(403)
        }
    }

    def index = {
        redirect(action: "list", params: params)
    }

    def list = {
        onlyLoggedInUsers();

        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [econInfoInstanceList: EconInfo.list(params), econInfoInstanceTotal: EconInfo.count()]
    }

    def create = {
        onlyLoggedInUsers();

        def econInfoInstance = new EconInfo()
        econInfoInstance.properties = params
        return [econInfoInstance: econInfoInstance]
    }

    def save = {
        def econInfoInstance = new EconInfo(params)
        if (econInfoInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), econInfoInstance.id])}"
            redirect(action: "show", id: econInfoInstance.id)
        }
        else {
            render(view: "create", model: [econInfoInstance: econInfoInstance])
        }
    }

    def show = {
        onlyLoggedInUsers();

        def econInfoInstance = EconInfo.get(params.id)
        if (!econInfoInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
            redirect(action: "list")
        }
        else {
            [econInfoInstance: econInfoInstance]
        }
    }

    def edit = {
        onlyLoggedInUsers();

        def econInfoInstance = EconInfo.get(params.id)
        if (!econInfoInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
            redirect(action: "list")
        }
        else {
            return [econInfoInstance: econInfoInstance]
        }
    }

    def update = {
        onlyLoggedInUsers();

        def econInfoInstance = EconInfo.get(params.id)
        if (econInfoInstance) {
            if (params.version) {
                def version = params.version.toLong()
                if (econInfoInstance.version > version) {
                    
                    econInfoInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'econInfo.label', default: 'EconInfo')] as Object[], "Another user has updated this EconInfo while you were editing")
                    render(view: "edit", model: [econInfoInstance: econInfoInstance])
                    return
                }
            }
            econInfoInstance.properties = params
            if (!econInfoInstance.hasErrors() && econInfoInstance.save(flush: true)) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), econInfoInstance.id])}"
                redirect(action: "show", id: econInfoInstance.id)
            }
            else {
                render(view: "edit", model: [econInfoInstance: econInfoInstance])
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
            redirect(action: "list")
        }
    }

    def delete = {
        onlyLoggedInUsers();

        def econInfoInstance = EconInfo.get(params.id)
        if (econInfoInstance) {
            try {
                econInfoInstance.delete(flush: true)
                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
                redirect(action: "list")
            }
            catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
                redirect(action: "show", id: params.id)
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'econInfo.label', default: 'EconInfo'), params.id])}"
            redirect(action: "list")
        }
    }

    def mostrar = {
      Town town = Town.get(params.id)

      // mirar si té pare.
      def dadesPapuchi = [:]
      if (town.parent) {
        def tmpList = EconInfo.findAllByAfecta(town.parent);
        for (tmp in tmpList) {
          if (dadesPapuchi[tmp.nom]) {
            EconInfo average = new EconInfo();
            average.nom = tmp.nom;
            average.afecta = tmp.afecta;
            average.valor = (dadesPapuchi[tmp.nom].valor + tmp.valor) / 2
            dadesPapuchi[tmp.nom] = average;
          } else {
            dadesPapuchi[tmp.nom] = tmp
          }
        }
      }

      def dades = merge(EconInfo.findAllByAfecta(town))

      def dadesNormalitzades = normalize(dades, dadesPapuchi)
      [ town : town , dades : dades , dadesPapuchi : dadesPapuchi, dadesNormalitzades : dadesNormalitzades ]
    }

    /**
     * Torna un mapa ['nom' -> [norm_dada, norm_dada_pare]]
     * Normalització és sobre 100
     */
    private normalize(def dades, def dadesPapuchi) {
      def mapa = [:]
      for (dada in dades) {
        // agafar nom.
        def dadaPare = dadesPapuchi[dada.nom]
        if (dadaPare) {

          // normalitzar!
          if (dada.valor > dadaPare.valor) {
            mapa[dada.nom] = [100,java.lang.Math.round(( dadaPare.valor * 100 ) / dada.valor)]
          } else if (dada.valor < dadaPare.valor) {
            mapa[dada.nom] = [java.lang.Math.round((dada.valor * 100)/dadaPare.valor),100]
          } else {
            mapa[dada.nom] = [50,50]
          }

        }
      }
      mapa;
    }

    // agafa les dades de diverses fonts en fa la mitjana.
    private merge(def dades) {
      def mapa = [:]
      for (dada in dades) {
        if (mapa[dada.nom]) {
            EconInfo average = new EconInfo();
            average.nom = dada.nom;
            average.afecta = dada.afecta;
            average.valor = (mapa[dada.nom].valor + dada.valor) / 2
            average.font = mapa[dada.nom].font + ", " + dada.font
            mapa[dada.nom] = average;
          // fer mitjana
        } else {
          mapa[dada.nom] = dada;
        }
      }
      mapa.values().toList()
    }

}
